local storyboard = require( "storyboard" )
local Player = {}

function Player:new(gravity,ix,iy)
   local player = display.newGroup()
   player.gravity = gravity
   player.x,player.y=ix,iy
   player.beingPisssh = false
   player.pishTimeout = 0
   player.sliding = false
   player.confussionTimeout = 0
   player.timeUsingMask = 0

   player.maskID = INITIAL_MASK

   --Helper attributes
   player.speedMaskModifier = 1
   player.beingPisssh = false
   player.beingPissshTimeout = 0
   player.lookingLeft = false

   -- properties
   --player.sprite = display.newImage(player, 'resources/sprites/character.png',0, 0)
   --player.sprite:scale(0.15,0.15)
   local spriteSheetInfo = require('resources.sprites.atlasses.character1-hd')
   local spriteSheet     = graphics.newImageSheet("resources/sprites/atlasses/character1-hd.png", spriteSheetInfo:getSheet())

   local spriteSheetInfoMask = require('resources.sprites.atlasses.character2-hd')
   local spriteSheetMask     = graphics.newImageSheet("resources/sprites/atlasses/character2-hd.png", spriteSheetInfoMask:getSheet())

   local spriteSheetInfoMask2 = require('resources.sprites.atlasses.character3-hd')
   local spriteSheetMask2     = graphics.newImageSheet("resources/sprites/atlasses/character3-hd.png", spriteSheetInfoMask2:getSheet())

   local spriteSheetInfoStates = require('resources.sprites.atlasses.statesmask1-hd')
   local spriteSheetStates     = graphics.newImageSheet("resources/sprites/atlasses/statesmask1-hd.png", spriteSheetInfoStates:getSheet())

   local sequenceData = {
      { name="standby1", sheet=spriteSheetStates,     frames={3,4}, time=250, loopCount=0 },
      { name="standby2", sheet=spriteSheetStates,     frames={5}, time=250, loopCount=0 },
      { name="standby3", sheet=spriteSheetMask2,     frames={10}, time=250, loopCount=0 },
      { name="falling1", sheet=spriteSheetStates,     frames={1}, time=250, loopCount=0 },
      { name="falling2", sheet=spriteSheetStates,     frames={2}, time=250, loopCount=0 },
      { name="falling3", sheet=spriteSheetMask2,     frames={9}, time=250, loopCount=0 },
      { name="walk1",    sheet=spriteSheet,         start=1, count=8, time=250, loopCount=0 },
      { name="walk2",    sheet=spriteSheetMask, start=1, count=8, time=250, loopCount=0 },
      { name="walk3",    sheet=spriteSheetMask2, start=1, count=8, time=250, loopCount=0 }
   }
   player.sprite = display.newSprite(player,spriteSheet, sequenceData )
   player.sprite:scale(0.33,0.33)

   player.life = 100
   player.lifeText = display.newText({
      parent = player,
      y = -Y*0.05,
      text = '100',
      fontSize = 8, font=Font.get('seagram')
   })
   player.lifeText.alpha = 0

   player.lifeLine = display.newRect (player, 0 , Y * 0.13, X * 0.12, 3)
   player.lifeLine.originalWidth = player.lifeLine.width
   player.lifeLine:setFillColor( 0, 1, 0, 1 )
   player.lifeLine:setStrokeColor( 0, 1, 0, 1 )
   player.lifeLine.strokeWidth = 3

   function player:getReferencePos() return self.x,self.y + self.sprite.contentHeight*0.5 end
   function player:resetPlayerState()
   	self.sliding = false
   	self.beingPisssh = false
   end
   function player:applyInitialMask()
      --self.maskSprite:setFillColor(1,1,1,1)
      --self.sprite = display.newImage(player, 'resources/sprites/character.png',0, 0)
      --self.sprite:scale(0.15,0.15)
      self.speedMaskModifier = 1
      self.maskID = INITIAL_MASK
   end

   function player:applyRedMask()
      --logger:debug('RED MASK')

      if self.maskID == RED_MASK then
         self:applyInitialMask()
         local currentScene = storyboard.getScene(storyboard.getCurrentSceneName())
         currentScene.hud.mask2Btn.cooldown = RED_MASK_COOLDOWN
      else
         self.maskID = RED_MASK
         --self.maskSprite:setFillColor(1,0,0,1)
         --self.sprite = display.newImage(player, 'resources/sprites/character_mask1.png',0, 0)
         --self.sprite:scale(0.15,0.15)

      end
   end

   function player:applyBlueMask()
      --logger:debug('BLUE MASK')

      if self.maskID == BLUE_MASK then
         self:applyInitialMask()
         local currentScene = storyboard.getScene(storyboard.getCurrentSceneName())
         currentScene.hud.mask1Btn.cooldown = BLUE_MASK_COOLDOWN
      else
         self.maskID = BLUE_MASK
         self.speedMaskModifier = 2
         --self.sprite = display.newImage(player, 'resources/sprites/character_mask1.png',0, 0)
         --self.sprite:scale(0.15,0.15)
         --self.maskSprite:setFillColor(0,0,1,1)
         --self.speedMaskModifier = 0.2
      end
   end

   player:applyInitialMask()

   function player:getMask()
      return self.maskID
   end

   function player:setMask(mask)
      --self.pishTimeout = 100 / 1000
      local currentScene = storyboard.getScene(storyboard.getCurrentSceneName())
      currentScene:createPishCloud2(self.x,self.y)
      self.timeUsingMask = 0

      if mask == RED_MASK then
         self:applyRedMask()
      elseif mask == BLUE_MASK then
         self:applyBlueMask()
      else
         assert(false,'BAD MASK INPUT')
      end
   end

   function player:isAlive() return self.life > 0 end

   function player:playDead()
      self.sprite:setSequence('falling'..self.maskID)
      self.lifeLine.alpha = 0;
      transition.to(
            self,
            {
               time = 500,
               y = self.y + Y * 0.9,
               onComplete=function()
                  DisplayObjectUtils.safeRemove(player)
               end
            }
         )
      logger:debug('%d %d',self.dx,self.dy)
      if math.abs(self.dx) > math.abs(self.dy) and self.dx < 0 then return true end
      if math.abs(self.dx) < math.abs(self.dy) and self.dy < 0 then return true end
      return false
   end

   function player:lifeUpdate(delta)
      local prevLife = self.life
      self.life = math.max(self.life + delta,0)

   end
   function player:damagePlayer (damage)
      self:lifeUpdate(-damage)
   end
   function player:updateLifeText()
      self.lifeText.text = math.ceil(self.life)
      player.lifeLine.width =  player.lifeLine.originalWidth * (self.life / 100)
      player.lifeText.text = self.life .. '/100'

   end
   function player:setBeingPisssh(newPisssh)
   	self.beingPisssh = newPisssh
   end
   function player:isBeingPisssh()
   	return self.beingPisssh
   end

   function player:yell()
      local thisPlayerYell = math.random(#playerYells)
      audio.play(playerYells[thisPlayerYell],{channel=1})
      local thisPisssh = math.random(#pissshs)
      audio.play(pissshs[thisPisssh],{channel=2})
   end

   function player:walkSound()
      local thisWalk = math.random(#playerWalk)
      audio.setVolume( 0.15, { channel=3 } )
      audio.play(playerWalk[thisWalk],{channel=3})
   end

   function player:runSound()
      local thisRun = math.random(#playerRun)
      audio.setVolume( 0.15, { channel=3 } )
      audio.play(playerRun[thisRun],{channel=3})
   end

   function player:maskSound()
      -- local thisRun = math.random(#playerRun)
      audio.play(maskChange[1],{channel=4})
   end

   function player:applyConfussion()
      self.confussionTimeout = CONFUSSION_TIMEOUT
   end
   function player:setSliding(newValue)
   	self.sliding = newValue
   end
   function player:isSliding()
   	return self.sliding
   end
   function player:centerCamera(gameWorld)
      local dx = halfX - player.x
      local dy = halfY - player.y
      gameWorld:translate( dx, dy )
   end
   function player:update(delta)
      self:updateLifeText()
      self.confussionTimeout = self.confussionTimeout - delta
      self.pishTimeout = self.pishTimeout - delta
      self.timeUsingMask = self.timeUsingMask + delta

      if(self:isAlive() == false) then
         return
      end

      if self.maskID == RED_MASK and self.timeUsingMask > RED_MASK_TIME then
         self:setMask(RED_MASK)
      end

      if self.maskID == BLUE_MASK and self.timeUsingMask > BLUE_MASK_TIME then
         self:setMask(BLUE_MASK)
      end

      if self.beingPisssh or self.pishTimeout > 0 then
         self.yell()
         self.beingPissshTimeout = self.beingPissshTimeout - delta
         if self.beingPissshTimeout <= 0 then
            local currentScene = storyboard.getScene(storyboard.getCurrentSceneName())
            currentScene:createPishCloud(self.x,self.y)
            self.beingPissshTimeout = PPISSSHTIMEOUT
         end
      end

      local speedBase = 400
      local speed = speedBase

      if LEVEL == 1 then
         speed = speed * 0.5
      end

      speed = speed * self.speedMaskModifier

      if self.confussionTimeout > 0 or self.maskID == RED_MASK then speed = -speed end

      local gx,gy = gravity.x,gravity.y
      if self.isSliding then
         gx,gy = gravity.smoothX,gravity.smoothY
      end

      local dx,dy = math.floor(gx*speed*delta), math.floor(gy*speed*delta)
      self:translate(dx,dy)
      self.dx,self.dy = dx,dy

      local standbySeq = 'standby'..self.maskID
      local walkSeq = 'walk'..self.maskID
      local fallingSeq = 'falling'..self.maskID

      if math.abs(dx) + math.abs(dy) > 0 then
         local currentScene = storyboard.getScene(storyboard.getCurrentSceneName())
         local nx,ny = self.x,self.y
         timer.performWithDelay(
            50,
            function()
               if self.parent then
                  currentScene:createPishCloud(nx,ny + self.sprite.contentHeight*0.5,0.1,0.25,true)

                  if self.speedMaskModifier > 1 then
                     self.runSound()
                  else
                     self.walkSound()
                  end
               end
            end
         )
         --logger:debug(self.sprite.sequence)

         if self.sprite.sequence ~= walkSeq then
            self.sprite:setSequence(walkSeq)
            self.sprite:play()
         end

         if dx > 0 and self.lookingLeft then
            self.sprite:scale(-1,1)
            self.lookingLeft = false
         end
         if dx < 0 and self.lookingLeft == false then
            self.sprite:scale(-1,1)
            self.lookingLeft = true
         end
      else
         if self.sprite.sequence ~= standbySeq then
            self.sprite:setSequence(standbySeq)
            self.sprite:play()
         end
      end

      gameWorld:translate(-dx, -dy)
   end

   return player
end

return Player